<?php

 /**
  * @package JooS
  * @subpackage PHPackager
  */

  require_once "JooS/PHPackager/DOM/Element.php";

  require_once "JooS/PHPackager/DOM/Element/Relations/Interface.php";

  abstract class JooS_PHPackager_DOM_Element_Relations_Abstract extends JooS_PHPackager_DOM_Element implements JooS_PHPackager_DOM_Element_Relations_Interface {
    /**
     * @var string
     */
    private $_compiledCode = null;

    /**
     * @return string
     */
    public function getCompiledCode() {
      return $this->_compiledCode;
    }

    /**
     * @param string $code
     * @return JooS_PHPackager_DOM_Element_Relations_Abstract
     */
    public function setCompiledCode($code) {
      $this->_compiledCode = $code;
      return $this;
    }

    /**
     * @return JooS_PHPackager_DOM_Element_Relations_Abstract
     */
    public function make() {
      $_syntax = $this->getSyntaxLanguage();
      $_expr = $this->getNode()->textContent;

      $_code = JooS_Syntax_Compiler::newInstance($_syntax)->compile($_expr);
      if ($_code === false) {
        require_once "JooS/PHPackager/DOM/Exception.php";

        throw new JooS_PHPackager_DOM_Exception("Parse Error in '" . $this->getNode()->tagName . "' tag");
      }
      $this->setCompiledCode($_code);
      
      return $this;
    }

    /**
     * @return JooS_PHPackager_DOM_Element_Relations_Abstract
     */
    public function install() {
      require_once "JooS/CodeGenerator/Method.php";
      require_once "JooS/PHPackager/DOM/Element/Package.php";
      require_once "JooS/Event/Phpackager/Package/Method/Create.php";

      $_name = "_init" . ucfirst(strtolower($this->getNode()->tagName));
      $_code = "return " . $this->getCompiledCode() . ";";
      
      $newMethod = JooS_CodeGenerator_Method::newInstance($_name)
        ->setVisibility(JooS_CodeGenerator_Method::VISIBILITY_PROTECTED)
        ->setBody($_code);

      JooS_Event_Phpackager_Package_Method_Create::getInstance()
        ->setMethod($newMethod)
        ->notify();

      return $this;
    }
  }
